"""
后台管理订单视图
"""
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAdminUser
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters
from django.db.models import F
from django.db import transaction
from pecco_site.models import Order, OrderStatusHistory, ProductVariant
from ..serializers.order import (
    AdminOrderSerializer,
    AdminOrderListSerializer,
    UpdateOrderStatusSerializer
)
import logging

logger = logging.getLogger(__name__)


class AdminOrderViewSet(viewsets.ModelViewSet):
    """后台订单管理视图集"""
    permission_classes = [IsAdminUser]
    queryset = Order.objects.all().prefetch_related('items', 'status_history').select_related('user')
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['status', 'user']
    search_fields = ['order_number', 'shipping_full_name', 'shipping_phone', 'user__email']
    ordering_fields = ['created_at', 'updated_at', 'total_price']
    ordering = ['-created_at']
    
    def get_serializer_class(self):
        if self.action == 'list':
            return AdminOrderListSerializer
        elif self.action == 'update_status':
            return UpdateOrderStatusSerializer
        return AdminOrderSerializer
    
    @action(detail=True, methods=['post'])
    def update_status(self, request, pk=None):
        """更新订单状态"""
        order = self.get_object()
        serializer = UpdateOrderStatusSerializer(data=request.data)

        if serializer.is_valid():
            new_status = serializer.validated_data['status']
            note = serializer.validated_data.get('note', '')
            tracking_number = serializer.validated_data.get('tracking_number', '')

            old_status = order.status

            # 如果状态没有变化，直接返回
            if old_status == new_status:
                logger.info(f"订单 {order.order_number} 状态未变化，跳过更新")
                return Response(AdminOrderSerializer(order).data)

            with transaction.atomic():
                # 场景 1: 从非取消状态变更为取消状态 -> 释放库存
                if old_status != 'cancelled' and new_status == 'cancelled':
                    logger.info(f"管理员取消订单 {order.order_number}，开始释放库存")

                    # 遍历订单项目，释放库存
                    for item in order.items.all():
                        if item.variant:
                            # 使用 F 表达式原子增加库存
                            updated_count = ProductVariant.objects.filter(
                                id=item.variant.id
                            ).update(stock=F('stock') + item.quantity)

                            if updated_count > 0:
                                logger.info(
                                    f"库存释放成功: 订单 {order.order_number}, "
                                    f"商品 {item.product_name} (variant_id={item.variant.id}), "
                                    f"释放数量 {item.quantity}"
                                )
                            else:
                                logger.error(
                                    f"库存释放失败: 订单 {order.order_number}, "
                                    f"商品 {item.product_name} (variant_id={item.variant.id}), "
                                    f"变体可能已被删除"
                                )

                # 场景 2: 从取消状态变更为其他状态 -> 重新扣减库存
                elif old_status == 'cancelled' and new_status != 'cancelled':
                    logger.info(f"管理员恢复订单 {order.order_number}，开始重新扣减库存")

                    # 第一步：预校验所有商品的库存是否充足
                    insufficient_stock_items = []
                    for item in order.items.all():
                        if item.variant:
                            # 刷新 variant 数据，获取最新库存
                            variant = ProductVariant.objects.get(id=item.variant.id)
                            if variant.stock < item.quantity:
                                insufficient_stock_items.append({
                                    'product_name': item.product_name,
                                    'variant_name': item.variant_name,
                                    'required': item.quantity,
                                    'available': variant.stock
                                })
                                logger.warning(
                                    f"库存不足: 订单 {order.order_number}, "
                                    f"商品 {item.product_name} (variant_id={item.variant.id}), "
                                    f"需要 {item.quantity}, 可用 {variant.stock}"
                                )

                    # 如果有库存不足的商品，返回错误
                    if insufficient_stock_items:
                        error_messages = []
                        for item in insufficient_stock_items:
                            error_messages.append(
                                f"{item['product_name']} ({item['variant_name']}): "
                                f"Need {item['required']} item(s), only {item['available']} available"
                            )
                        logger.error(
                            f"订单恢复失败 - 库存不足: {order.order_number}, "
                            f"详情: {', '.join(error_messages)}"
                        )
                        return Response(
                            {
                                'error': 'Insufficient stock to restore this order',
                                'details': error_messages
                            },
                            status=status.HTTP_400_BAD_REQUEST
                        )

                    # 第二步：扣减库存（使用 F 表达式 + 条件更新）
                    failed_items = []
                    for item in order.items.all():
                        if item.variant:
                            # 使用 F 表达式原子扣减库存，并确保库存充足
                            updated_count = ProductVariant.objects.filter(
                                id=item.variant.id,
                                stock__gte=item.quantity  # 确保库存充足
                            ).update(stock=F('stock') - item.quantity)

                            if updated_count > 0:
                                logger.info(
                                    f"库存扣减成功: 订单 {order.order_number}, "
                                    f"商品 {item.product_name} (variant_id={item.variant.id}), "
                                    f"扣减数量 {item.quantity}"
                                )
                            else:
                                # 如果更新失败，说明在预校验和扣减之间库存被其他操作改变了
                                logger.error(
                                    f"库存扣减失败（并发冲突）: 订单 {order.order_number}, "
                                    f"商品 {item.product_name} (variant_id={item.variant.id})"
                                )
                                failed_items.append({
                                    'product_name': item.product_name,
                                    'variant_name': item.variant_name
                                })

                    # 如果有扣减失败的商品，返回错误（事务会自动回滚）
                    if failed_items:
                        error_messages = []
                        for item in failed_items:
                            error_messages.append(
                                f"{item['product_name']} ({item['variant_name']}): "
                                f"Insufficient stock (concurrent update detected)"
                            )
                        logger.error(
                            f"订单恢复失败 - 并发冲突: {order.order_number}, "
                            f"详情: {', '.join(error_messages)}"
                        )
                        return Response(
                            {
                                'error': 'Insufficient stock to restore this order. Please refresh the page and try again.',
                                'details': error_messages
                            },
                            status=status.HTTP_400_BAD_REQUEST
                        )

                # 更新订单状态
                order.status = new_status
                if tracking_number:
                    order.tracking_number = tracking_number
                order.save()

                # 记录状态变更
                status_note = note or f'Status changed to {order.get_status_display()}'
                if old_status != 'cancelled' and new_status == 'cancelled':
                    status_note += ' (库存已释放)'
                elif old_status == 'cancelled' and new_status != 'cancelled':
                    status_note += ' (库存已重新扣减)'

                OrderStatusHistory.objects.create(
                    order=order,
                    status=new_status,
                    note=status_note
                )

                logger.info(
                    f"订单状态更新成功: {order.order_number}, "
                    f"{old_status} -> {new_status}, 操作人: {request.user.username}"
                )

            return Response(AdminOrderSerializer(order).data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    @action(detail=True, methods=['patch'])
    def update_note(self, request, pk=None):
        """更新管理员备注"""
        order = self.get_object()
        admin_note = request.data.get('admin_note', '')
        
        order.admin_note = admin_note
        order.save()
        
        return Response(AdminOrderSerializer(order).data)

